/*
 * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

#include "sample_comm_nnie.h"
#include "sample_media_ai.h"
#include "ai_infer_process.h"
#include "yolov2_hand_detect.h"
#include "vgs_img.h"
#include "ive_img.h"
#include "misc_util.h"
#include "hisignalling.h"

#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>

#include "rec/b64/b64.h"
#define MAXLINE 1024
int base64_length;

#include "sample_comm_ive.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* End of #ifdef __cplusplus */

#define HAND_FRM_WIDTH     1920
#define HAND_FRM_HEIGHT    1080
#define DETECT_OBJ_MAX     32
#define RET_NUM_MAX        4
#define DRAW_RETC_THICK    2    // Draw the width of the line
#define WIDTH_LIMIT        32
#define HEIGHT_LIMIT       32
#define IMAGE_WIDTH        224  // The resolution of the model IMAGE sent to the classification is 224*224
#define IMAGE_HEIGHT       224
#define MODEL_FILE_GESTURE    "/userdata/models/hand_classify/hand_gesture.wk" // darknet framework wk model

static int biggestBoxIndex;
static IVE_IMAGE_S img;
static DetectObjInfo objs[DETECT_OBJ_MAX] = {0};
static RectBox boxs[DETECT_OBJ_MAX] = {0};
static RectBox objBoxs[DETECT_OBJ_MAX] = {0};
static RectBox remainingBoxs[DETECT_OBJ_MAX] = {0};
static RectBox cnnBoxs[DETECT_OBJ_MAX] = {0}; // Store the results of the classification network
static RecogNumInfo numInfo[RET_NUM_MAX] = {0};
static IVE_IMAGE_S imgIn;
static IVE_IMAGE_S imgDst;
static VIDEO_FRAME_INFO_S frmIn;
static VIDEO_FRAME_INFO_S frmDst;
int uartFd = 0;

/*
 * ive image to video frame.
 * Copy the data pointer, do not copy the data.
 */
// int OrigImgToFrm(const IVE_IMAGE_S *img, VIDEO_FRAME_INFO_S* frm)
// {
//     static const int chnNum = 2;
//     IVE_IMAGE_TYPE_E enType = img->enType;
//     if (memset_s(frm, sizeof(*frm), 0, sizeof(*frm)) != EOK) {
//         HI_ASSERT(0);
//     }

//     frm->stVFrame.u32Width = img->u32Width;
//     frm->stVFrame.u32Height = img->u32Height;

//     if (enType == IVE_IMAGE_TYPE_YUV420SP) {
//         frm->stVFrame.enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420;
//     } else if (enType == IVE_IMAGE_TYPE_YUV422SP) {
//         frm->stVFrame.enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_422;
//     } else {
//         HI_ASSERT(0);
//         return -1;
//     }

//     for (int i = 0; i < chnNum; i++) {
//         frm->stVFrame.u64PhyAddr[i] = img->au64PhyAddr[i];
//         frm->stVFrame.u64VirAddr[i] = img->au64VirAddr[i];
//         frm->stVFrame.u32Stride[i] = img->au32Stride[i];
//     }
//     return 0;
// }
char * pic_base64(char* firname) {
    char *r;

    FILE *fq;
    if( ( fq = fopen(firname,"rb") ) == NULL ){
        printf("File open.\n");
        exit(1);
    }

    fseek(fq,0,SEEK_END);
    long length  = ftell(fq);

    base64_length = length/3 * 4;
    if (length % 3 != 0)  
        base64_length += 3;

    // printf("%ld\n",length);
    fseek(fq,0,SEEK_SET);

    char *buffer;
    buffer = malloc(length + 1);
    buffer[length] = "\x00";

    fread(buffer, 1, length, fq);
    r = b64_encode(buffer, length); 
  
    fclose(fq);
    return r;
}


int MySocket(){
    int   sockfd, len;
    struct sockaddr_in  servaddr;
    char myip[] = "120.25.225.38";
    char data_buf[1025];
    char read_buf[1025];
    char *b64_img;

    b64_img = pic_base64("./qwq1.yuv"); //图片转 base64

    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
        printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);
        return 0;
    }

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(5555);
    if( inet_pton(AF_INET, myip, &servaddr.sin_addr) <= 0){
        printf("inet_pton error for %s\n",myip);
        return 0;
    }

    if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
        printf("connect error: %s(errno: %d)\n",strerror(errno),errno);
        return 0;
    }
    
    sprintf(data_buf, "imag, size:%d\x00", base64_length); //发送图片长度
    write(sockfd, data_buf, strlen(data_buf));

    memset(read_buf, 0, 1025);
    read(sockfd, read_buf, MAXLINE);
    printf("%s\n", read_buf);

    sleep(1);
    
    memset(read_buf, 0, 1025);
    read(sockfd, read_buf, MAXLINE);
    printf("%s\n", read_buf);


    if (strcmp(read_buf,"OK"))
    {
        printf("end\n");
        close(sockfd);
        return 0;

    }
    SAMPLE_PRT("----SNED START----:\n");
        

    int index, rest;
    rest = base64_length;
    index = 0;
    while(rest >= 1024){ //图片分块发包
        rest -= 1024;
        // printf("%d %d %d %d\n", rest, base64_length, index, index * 1024);
        if (rest >= 1024 || rest == 0)
        {
            len = 1024;
            if(len != write(sockfd, b64_img + index * 1024 , len)){
                printf("write fail.\n");
                break;
            }
        }
        else{
            len = rest;
            if(len != write(sockfd, b64_img + index * 1024 , len)){
                printf("write fail.\n");
            }
            break;
        }
        index++;
    }
    SAMPLE_PRT("----SNED END----:\n");

    memset(read_buf, 0, 1025);
    read(sockfd, read_buf, MAXLINE);
    SAMPLE_PRT("----THE NAME----:\n");
    printf("%s\n", read_buf);
    SAMPLE_PRT("----THE NAME----:\n");
    close(sockfd);
     
    int i = 0;
    while(read_buf[i] != '\n')
        i++;
    read_buf[i] = '\x00';
    sprintf(data_buf, "echo %s >> ./name.log\x00", read_buf); //log 记录
    // printf("%s\n", data_buf); 
    system(data_buf);
    return 0;
}

HI_S32 MyCUT(VIDEO_FRAME_INFO_S *srcFrm, VIDEO_FRAME_INFO_S *dstFrm)
{
    int ret;
    int num = 0;
    HI_S32 s32Ret;
    IVE_IMAGE_S img2;
    // VIDEO_FRAME_INFO_S frm;


    ret = FrmToOrigImg((VIDEO_FRAME_INFO_S*)srcFrm, &img);
    SAMPLE_CHECK_EXPR_RET(ret != HI_SUCCESS, ret, "hand detect for YUV Frm to Img FAIL, ret=%#x\n", ret);

    FILE* PicFd = fopen("./qwq1.yuv", "wb");

    // FILE* pFpSrc = fopen("./lx2.yuv", "rb");
    
    // s32Ret = SAMPLE_COMM_IVE_CreateImage(&img2, IVE_IMAGE_TYPE_YUV420SP, HAND_FRM_WIDTH, HAND_FRM_HEIGHT);

    // s32Ret = SAMPLE_COMM_IVE_ReadFile(&img2, pFpSrc);
    // SAMPLE_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, "Error(%#x), Read src file failed!\n", s32Ret);

    // s32Ret = OrigImgToFrm(&img2, dstFrm);

    SAMPLE_PRT("----qwq qwq----:\n");
    SAMPLE_PRT("----qwq qwq----:\n");
    SAMPLE_PRT("----qwq qwq----:\n");
    SAMPLE_PRT("----qwq qwq----:\n");
    SAMPLE_PRT("----qwq qwq----:\n");
    SAMPLE_PRT("----qwq qwq----:\n");
    SAMPLE_PRT("----qwq qwq----:\n");
    SAMPLE_PRT("----qwq qwq----:\n");

    SAMPLE_COMM_IVE_WriteFile(&img, PicFd);
    SAMPLE_PRT("SAMPLE_COMM_IVE_WriteFile GOOD!\n");

    MySocket();
    SAMPLE_PRT("MySocket Finish!\n");

    IveImgDestroy(&img);
    IVE_CLOSE_FILE(PicFd);
    // IVE_CLOSE_FILE(pFpSrc);

    return ret;
}

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
